import React, {useRef, useState} from 'react';
import {App, Badge, Button, Flex, Space, Switch, TableProps} from 'antd';
import {Form, Input, Popconfirm, Table, Typography} from 'antd';
import RequestHandler from "http/RequestHandler";
import {nanoid} from "@reduxjs/toolkit";
import {PlusOutlined} from "@ant-design/icons";
import {DetailItem} from "type/entity/ReportDetail";
import {useAppDispatch, useAppSelector} from "storage/redux/hook";
import {fetchRemoveItem, updateDetailItem} from "storage/redux/reducer/reportDetail";

interface EditableCellProps extends React.HTMLAttributes<HTMLElement> {
    editing: boolean;
    dataIndex: string;
    title: any;
    inputType: 'switch' | 'text';
    record: DetailItem;
    index: number;
}

const EditableCell: React.FC<React.PropsWithChildren<EditableCellProps>> = ({
                                                                                editing,
                                                                                dataIndex,
                                                                                title,
                                                                                inputType,
                                                                                record,
                                                                                index,
                                                                                children,
                                                                                ...restProps
                                                                            }) => {
    const inputNode = inputType === 'text' ? <Input/> : <Switch/>;

    return (
        <td {...restProps}>
            {editing ?
                <Form.Item
                    name={dataIndex}
                    style={{margin: 0}}
                    rules={[
                        {
                            required: true,
                            message: `请填写${title}!`,
                        },
                    ]}
                >
                    {inputNode}
                </Form.Item>
                :
                children
            }
        </td>
    );
};

const EditTable: React.FC = () => {
    const isAddRef = useRef<boolean>(false);
    const [form] = Form.useForm();
    // const [data, setData] = useState<DetailItem[]>([]);
    const [editingKey, setEditingKey] = useState('');
    const {message} = App.useApp();
    const isEditing = (record: DetailItem) => record.key === editingKey;

    const data = useAppSelector(state => state.reportDetail.detailItems);
    const dispatch = useAppDispatch();

    // 编辑报销项目
    const edit = (record: Partial<DetailItem> & { key: React.Key }) => {
        form.setFieldsValue(record);
        setEditingKey(record.key);
    };

    const remove = async (key: string) => {
        await dispatch(fetchRemoveItem(key));
        message.success("删除成功");
    };

    const cancel = () => {
        if (isAddRef.current){
            dispatch(updateDetailItem(data.filter(item => item.key !== editingKey)));
            isAddRef.current = false;
        }
        setEditingKey('');
    };


    const addItem = () => {
        isAddRef.current = true;
        const key = nanoid(32);
        const temp: DetailItem = {
            key: key,
            show: true,
            defaultSelected: false,
            label: ""
        };
        dispatch(updateDetailItem([...data, temp]));
        form.setFieldsValue(temp);
        setEditingKey(key);
    };

    const save = async (key: React.Key) => {
        try {
            const row = (await form.validateFields()) as DetailItem;
            const newData = [...data];
            // 数据修改前的索引
            const index = newData.findIndex((item) => key === item.key);
            if (index > -1) {
                const updateData = {...newData[index], ...row};
                if (isAddRef.current){
                    await RequestHandler.put<boolean>("/record/report/detail/item", updateData);
                    message.success("添加数据成功");
                }else {
                    await RequestHandler.post<boolean>("/record/report/detail/item", updateData);
                    message.success("修改数据成功");

                }
                newData.splice(index, 1, updateData);
                dispatch(updateDetailItem(newData));
                setEditingKey('');
                isAddRef.current = false;
            } else {
                message.error("没有找到编辑项目");
            }
        } catch (errInfo) {
            message.error("数据验证失败");
        }
    };

    const columns = [
        {
            dataIndex: 'index',
            title: '序号',
            width: 50,
            // align: 'center',
            editable: false,
            render: (_:any, __:any, index: number) => {
                return <strong> {index + 1} </strong>;
            }
        },
        {
            title: '报销项',
            dataIndex: 'label',
            editable: true,
            width: 120,
        },
        {
            title: '是否显示',
            dataIndex: 'show',
            width: 80,
            editable: true,
            render: (value: boolean) => <Badge color={value ? "green" : "red"}/>
        },
        {
            title: '默认选中',
            dataIndex: 'defaultSelected',
            width: 80,
            editable: true,
            render: (value: boolean) => <Badge color={value ? "green" : "red"}/>
        },
        {
            title: '操作',
            dataIndex: 'operation',
            width: 100,
            render: (_: any, record: DetailItem) => {
                const editable = isEditing(record);
                return editable ?
                    <span>
            <Typography.Link onClick={() => save(record.key)} style={{marginRight: 8}}>
              保存
            </Typography.Link>
            <Popconfirm title="Sure to cancel?" onConfirm={cancel}>
              <a>取消</a>
            </Popconfirm>
          </span>
                    :
                    <Space>
                        <Typography.Link disabled={editingKey !== ''} onClick={() => edit(record)}>
                            编辑
                        </Typography.Link>
                        <Popconfirm title={`确认要删除报销项目 [ ${record.label} ]?`} onConfirm={async () => remove(record.key)}>
                            <Button disabled={editingKey !== ''} danger type={"link"} >删除</Button>
                        </Popconfirm>
                    </Space>;
            },
        },
    ];

    const mergedColumns: TableProps['columns'] = columns.map((col) => {
        (col as any).align = "center";
        if (!col.editable) {
            return col;
        }
        return {
            ...col,
            onCell: (record: DetailItem) => ({
                record,
                inputType: col.dataIndex === 'label' ? 'text' : 'switch',
                dataIndex: col.dataIndex,
                title: col.title,
                editing: isEditing(record),
                align: "center",
            }),
        };
    });

    return (
        <Form form={form} component={false}>
            <Flex style={{ marginBottom: "10px" }} justify={"space-between"}>
                <Button type={"primary"} onClick={addItem} icon={<PlusOutlined/>}>添加报销项目</Button>
                <Badge status={ isAddRef.current ? "warning" : "default" } />
            </Flex>
            <Table
                size={"small"}
                components={{
                    body: {
                        cell: EditableCell,
                    },
                }}
                bordered
                dataSource={data}
                columns={mergedColumns}
                rowClassName="editable-row"
                // pagination={{
                //     onChange: cancel,
                // }}
            />
        </Form>
    );
};

export default EditTable;